package com.miaohy.demo.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.miaohy.demo.entity.TBasicUpload;
import com.miaohy.demo.mapper.TBasicUploadMapper;
import com.miaohy.demo.models.DownLoadFIleVO;
import com.miaohy.demo.models.UploadFileDTO;
import com.miaohy.demo.service.IBasicUploadService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.UUID;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author jobob
 * @since 2025-02-25
 */
@Slf4j
@Service
public class BasicUploadServiceImpl extends ServiceImpl<TBasicUploadMapper, TBasicUpload> implements IBasicUploadService {

    @Value("${upload-path:}")
    private String uploadPath;

    @Override
    public UploadFileDTO upload(MultipartFile multipartFile) {
        UploadFileDTO dto = new UploadFileDTO();
        String dateStr = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        String uuid = UUID.randomUUID().toString();
        Path rootPath = Paths.get(uploadPath, dateStr, uuid);

        File file = FileUtil.touch(rootPath.toString());
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(file);
            fileOutputStream.write(multipartFile.getBytes());

        } catch (Exception e) {
            log.error("upload err", e);
        } finally {
            try {
                if (ObjUtil.isNotNull(fileOutputStream)) {
                    fileOutputStream.flush();
                    fileOutputStream.close();
                }
            } catch (Exception e) {
                log.error("upload err", e);
            }
        }
        dto.setUuid(uuid);
        TBasicUpload basicUpload = new TBasicUpload();
        basicUpload.setContentType(multipartFile.getContentType());
        basicUpload.setFileUuid(uuid);
        basicUpload.setFileName(multipartFile.getOriginalFilename());
        basicUpload.setFilePath(dateStr + "/" + uuid);
        basicUpload.setFileSize((int) multipartFile.getSize());
        baseMapper.insert(basicUpload);
        return dto;
    }

    @Override
    public void download(DownLoadFIleVO vo, HttpServletResponse response) {
        TBasicUpload basicUpload = baseMapper.selectOne(Wrappers.<TBasicUpload>lambdaQuery()
                .eq(TBasicUpload::getFileUuid, vo.getUuid())
                .last("limit 1")
        );

        response.setContentType(basicUpload.getContentType());
        FileInputStream fileInputStream = null;
        try {
            response.setHeader("Content-Disposition",
                    String.format("attachment;filename=%s", URLEncoder.encode(basicUpload.getFileName(), "utf-8")));
            File file = new File(Paths.get(uploadPath, basicUpload.getFilePath()).toString());
            fileInputStream = new FileInputStream(file);
            OutputStream outputStream = response.getOutputStream();
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = fileInputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            outputStream.flush();
            outputStream.close();
            fileInputStream.close();
        } catch (Exception e) {
            log.error("download file err", e);
        }
    }
}
